package com.minisoft.utils;

import cn.hutool.http.HttpUtil;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.*;

public class SignatureAlgorithm {

    private static final String ALGORITHM = "HmacSHA1";
    private static final String ENCODING = "UTF-8";
    private static final String DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss'Z'";

    public static String generateSignature(String accessKeySecret, String method, String domain, Map<String, String> params) throws Exception {
        String urlParam = buildUrlParam(method, domain, params);
        String signature = hmacSha1(accessKeySecret, urlParam);
        return URLEncoder.encode(signature, ENCODING);
    }

    private static String buildUrlParam(String method, String domain, Map<String, String> params) {
        StringBuilder sb = new StringBuilder();
        sb.append(method).append(domain).append("/?");
        List<String> keys = new ArrayList<>(params.keySet());
        Collections.sort(keys);
        for (String key : keys) {
            sb.append(key).append("=").append(params.get(key)).append("&");
        }
        sb.deleteCharAt(sb.length() - 1);
        return sb.toString();
    }

    private static String hmacSha1(String accessKeySecret, String urlParam) throws NoSuchAlgorithmException, InvalidKeyException {
        Mac mac = Mac.getInstance(ALGORITHM);
        SecretKeySpec secretKeySpec = new SecretKeySpec(accessKeySecret.getBytes(StandardCharsets.UTF_8), ALGORITHM);
        mac.init(secretKeySpec);
        byte[] hmacSha1Bytes = mac.doFinal(urlParam.getBytes(StandardCharsets.UTF_8));
        return Base64.getEncoder().encodeToString(hmacSha1Bytes);
    }

    public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeyException {
        String accessKeySecret = "4w8Xo4AF25f669YB95l5";
        String method = "GET";
        String domain = "clink-openapi-test.cnhuafas.com";
        Map params = new HashMap<>();
        params.put("AccessKeyId", "1438ff588427d93d10a092b896a34ea4");
        params.put("Expires", "60");
        params.put("Timestamp", new SimpleDateFormat(DATE_FORMAT).format(new Date()));
        params.put("limit", "10");
        params.put("offset", "0");
        params.put("qno", "0000");
        params.put("cnos[0]", "0000");
        params.put("cnos[1]", "0001");
        try {
            String signature = generateSignature(accessKeySecret, method, domain, params);
            String url = "https://" + domain + "/list_clients";
            params.put("Signature",signature);
            String s = HttpUtil.get(url, params);
            System.out.println(s);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}